/*
	Copyright (c) 2010 <copyright holders>
	This source code is licensed under The MIT License,
	see the file LICENSE for details.
	*/

#ifndef ENTITYINTERPOLATOR_HPP
#define ENTITYINTERPOLATOR_HPP

#include <map>
#include <OGRE/OgreAny.h>
#include <OGRE/OgrePrerequisites.h>
#include <OGRE/OgreQuaternion.h>
#include <OGRE/OgreVector3.h>

#include "ForwardDecls.hpp"
#include "Spatial.hpp"

namespace spelprog2 {
namespace presentation {

enum SelectionMarker {
    SELECTIONMARK_OFF,
    SELECTIONMARK_FRIENDLY,
    SELECTIONMARK_ENEMY,
    SELECTIONMARK_ALLY,
    SELECTIONMARK_NEUTRAL
};

class EntityInterpolator {
    HIDE_EVIL_CONSTRUCTORS(EntityInterpolator);

    const LandscapeSpatials & spatials_;
    Ogre::SceneManager & sceneManager_;
    Ogre::SceneNode * sceneNode_;
    Ogre::Entity * entity_;
    Ogre::Vector3 position_;
    std::list< std::pair<Ogre::String, Ogre::String> > syncList;

    typedef std::map<std::string, std::string> ProgressionMap;
    ProgressionMap progressions_;
public:
    EntityInterpolator(const LandscapeSpatials & spatials, Ogre::int32 queryFlag,
        Ogre::SceneManager & sceneMan, const Ogre::String & model,
        Ogre::Real modelScale, const Ogre::Vector3 & initPos, Ogre::Radian initYaw = Ogre::Radian());
    virtual ~EntityInterpolator();

    static Ogre::Vector3 convertPosition(const sim::Int3d & pos);
    static Ogre::Vector3 convertPosition(const sim::Int2d & pos, const LandscapeSpatials & spatials);
    static Ogre::Radian convertAngle(sim::Int angle);
    const LandscapeSpatials & getSpatials() const { return spatials_; }

    void setEntityData(const Ogre::String & key, const Ogre::Any & data);

    virtual void gfxUpdate(float deltaTime);

    const Ogre::Vector3 & getPosition() const { return position_; }
    void setPosition(const Ogre::Vector3 & newPosition);
    void setRoll(Ogre::Radian newAngle);
    void setPitch(Ogre::Radian newAngle);
    void setYaw(Ogre::Radian newAngle);

    void setSelectionMarker(SelectionMarker marker);

    void enableSingleAnimation(const Ogre::String & name, bool reset);
    void enableLoopingAnimation(const Ogre::String & name, Ogre::Real startTime = 0);
    void synchronizeAnimations(Ogre::String & name1, Ogre::String & name2);
    void setAnimationWeight(const Ogre::String & name, Ogre::Real weight);
    void endAnimation(const Ogre::String & name);
    void beginSingleAnimation(const Ogre::String & name, const Ogre::String & follower = "");
};

}; //presentation
}; //spelprog2

#endif //ENTITYINTERPOLATOR_HPP